package cn.myzf.module.routes;

import cn.myzf.module.annotation.NettyResponsebody;
import cn.myzf.module.util.ResponseInfo;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.util.internal.StringUtil;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @package cn.myzf.module.routes
 * @Date Created in 2020/3/7 21:58
 * @Author myzf
 */
public class NettyDispatchcher extends HttpServlet<ResponseInfo> {




    public NettyDispatchcher() {
    }

    @Override
    protected void doInterceptor(FullHttpRequest request) {
        interceptors.forEach(interceptor -> {
            interceptor.preHandle(request);
        });
    }

    private String execlinkurl(String requestUrl) {

        if (!StringUtil.isNullOrEmpty(requestUrl)) {
            String regex = "/(.*do)?";
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(requestUrl);
            while (m.find()) {
                requestUrl =  m.group(1);
            }
        }
       return "/" + requestUrl;
    }

    @Override
    protected ResponseInfo doPost(FullHttpRequest request) {
        try {

            Map<String, String> parse1 = parse(request);
            String requestURI = request.getUri();
            requestURI = execlinkurl(requestURI);
                Method method = methodMap.get(requestURI);
                if (method!=null){
                    Parameter[] parameters = method.getParameters();
                    Object[] objects = new Object[parameters.length];
                    for (int i = 0; i < parameters.length; i++) {
                        Parameter parameter = parameters[i];
                        String name = parameter.getName();
                        Class<?> type = parameter.getType();
                        if (type.equals(FullHttpRequest.class)){
                            objects[i]=request;
                        }else if(type.equals(String.class)){
                            objects[i]= parse1.get(name);
                        }else{
                            Object o = type.newInstance();
                            for (Field field : type.getDeclaredFields()) {
                                field.setAccessible(true);
                                String fieldName = field.getName();
                                if (field.getType().equals(int.class)){
                                    field.set(o,Integer.parseInt(parse1.get(fieldName)));
                                }else {
                                    field.set(o,parse1.get(fieldName));
                                }
                            }
                            objects[i] = o;
                        }
                    }
                    Class<?> declaringClass = method.getDeclaringClass();
                    Object o = controllerInstance.getResourceInstances().get(declaringClass);
                    if (o==null){
                        o = declaringClass.newInstance();
                    }
                    Object invoke = method.invoke(o, objects);
                    String s = String.valueOf(((ResponseInfo)invoke).getMessage());
                    if (method.isAnnotationPresent(NettyResponsebody.class)){
                      return   ResponseInfo.build(s);
                    }else{
                        //todo 实现页面跳转解析
//                        if (invoke.getClass().equals(String.class)){
//                            re.getRequestDispatcher(prefix+s+suffix).forward(request,response);
////                          response.sendRedirect();
//                        }
                    }
                }else{
                    return ResponseInfo.build(ResponseInfo.CODE_INVILID_PARAMS,"服务器处理异常");

                }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
            return ResponseInfo.build(ResponseInfo.CODE_SYSTEM_ERROR,"服务器异常");
    }


    private Map<String, String> parse(FullHttpRequest request) throws IOException {
        HttpMethod method = request.getMethod();

        Map<String, String> parmMap = new HashMap<>();
        if (HttpMethod.GET == method) {
            // 是GET请求
            QueryStringDecoder decoder = new QueryStringDecoder(request.getUri());
            decoder.parameters().forEach((key, value) -> {
                // entry.getValue()是一个List, 只取第一个元素
                parmMap.put(key, value.get(0));
            });
        } else if (HttpMethod.POST == method) {
            // 是POST请求
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
            decoder.offer(request);
            List<InterfaceHttpData> parmList = decoder.getBodyHttpDatas();
            for (InterfaceHttpData parm : parmList) {
                Attribute data = (Attribute) parm;
                parmMap.put(data.getName(), data.getValue());
            }
        } else {
        }
        return parmMap;
    }
}
